package com.stt.videoprocess.base.service;

import com.stt.videoprocess.base.model.ProcessingStatus;
import com.stt.videoprocess.base.model.VideoTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.time.LocalDateTime;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 视频处理服务实现
 * 1. 创建处理任务
 * 2. 执行处理流程
 * 3. 状态维护和指标收集
 */
@Service
@Slf4j
public class VideoProcessingService {
    private final ConcurrentHashMap<String, VideoTask> taskStore = new ConcurrentHashMap<>();

    /**
     * 创建视频处理任务
     * @param file 上传的视频文件
     * @return 任务ID
     */
    public String createProcessingTask(MultipartFile file) {
        String taskId = UUID.randomUUID().toString();
        VideoTask task = new VideoTask();
        task.setTaskId(taskId);
        task.setOriginalFile(file.getOriginalFilename());
        task.setStatus(ProcessingStatus.INIT);
        task.setCreateTime(LocalDateTime.now());
        taskStore.put(taskId, task);
        
        // 启动异步处理
        new Thread(() -> processVideo(taskId)).start();
        log.info("创建新的视频处理任务，任务编号: {}", taskId);
        return taskId;
    }

    /**
     * 执行视频处理流程
     */
    private void processVideo(String taskId) {
        try {
            updateTaskStatus(taskId, ProcessingStatus.PROCESSING);

            // 处理步骤执行（串行执行，任意步骤失败则整体任务失败）
            // 1. 添加数字水印 - 调用applyWatermark()方法实现
            executeWithMetrics(taskId, "添加数字水印", this::applyWatermark);

            // 2. 调整视频分辨率 - 调用adjustResolution()方法实现
            executeWithMetrics(taskId, "调整视频分辨率", this::adjustResolution);

            // 3. 应用视频滤镜 - 调用applyFilter()方法实现
            executeWithMetrics(taskId, "应用视频滤镜", this::applyFilter);

            // 所有处理步骤完成后更新状态
            updateTaskStatus(taskId, ProcessingStatus.COMPLETED);
        } catch (Exception e) {
            log.error("任务处理失败: " + taskId, e);
            updateTaskStatus(taskId, ProcessingStatus.FAILED, e.getMessage());
            rollbackOperations(taskId);
        }
    }

    /**
     * 带指标记录的执行方法
     */
    private void executeWithMetrics(String taskId, String operationName, Runnable operation) {
        long startTime = System.currentTimeMillis();
        try {
            operation.run();
            log.info("任务：{} 正在处理: {}", taskId, operationName);
        } finally {
            long duration = System.currentTimeMillis() - startTime;
            log.info("任务：{} 处理 {}，耗时: {}毫秒", taskId, operationName, duration);
        }
    }

    // 以下为模拟处理方法（实际处理逻辑替换为日志输出）
    private void applyWatermark() {
        log.info("给视频添加水印中......");
        // 模拟处理耗时
        try { Thread.sleep(500); } catch (InterruptedException ignored) {}
    }

    private void adjustResolution() {
        log.info("给视频调整分辨率中......");
        try { Thread.sleep(800); } catch (InterruptedException ignored) {}
    }

    private void applyFilter() {
        log.info("给视频添加滤镜中......");
        try { Thread.sleep(300); } catch (InterruptedException ignored) {}
    }

    /**
     * 获取任务状态
     */
    public VideoTask getTaskStatus(String taskId) {
        return taskStore.get(taskId);
    }

    /**
     * 更新任务状态
     */
    private void updateTaskStatus(String taskId, ProcessingStatus status, String... errorMessage) {
        VideoTask task = taskStore.get(taskId);
        // 判断处理状态
        if(task.getStatus().equals(ProcessingStatus.INIT) && status.equals(ProcessingStatus.PROCESSING)) {
            task.setStatus(status);
        } else if (task.getStatus().equals(ProcessingStatus.PROCESSING) && status.equals(ProcessingStatus.COMPLETED)) {
            task.setStatus(status);
        }else if (task.getStatus().equals(ProcessingStatus.PROCESSING) && status.equals(ProcessingStatus.FAILED)) {
            task.setStatus(status);
        }else {
            log.info("状态流转错误......");
            return;
        }
        task.setUpdateTime(LocalDateTime.now());
        if (errorMessage.length > 0) {
            task.setErrorMessage(String.join(", ", errorMessage));
        }
    }

    /**
     * 操作回滚实现
     */
    private void rollbackOperations(String taskId) {
        log.warn("回滚任务: {}", taskId);
        // 根据实际需要实现回滚逻辑
    }
}